﻿using System;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Threading;
using Maelu.Classes;
using FFACETools;
using System.Data;
using System.Collections.Generic;
using System.Drawing;

namespace Maelu
{
    public partial class Form1 : Form
    {
        FFACE _FFACE { get; set; }

        //+800ms / checked checkbox.
        private volatile int antiSpam = 150;
        private volatile int myServer = 0;

        private DataTable dt = new DataTable("Test");
        private BindingSource bs;

        
        /* Matches: "Median</td>
                <td><span class=number-format>(\d+)</span>" */
        private volatile string regexItemPrice = @"Median.*\r\n.*?(\d+)";
        private volatile string regexItemName = @"<title>(.*) -";

        public Form1()
        {
            InitializeComponent();

            Process[] pol = Process.GetProcessesByName("pol");
            //make sure pol is running
            if (1 > pol.Length)
            {
                //let the user know what went wrong
                MessageBox.Show("Error: FFXI not found..", "Error");
                System.Environment.Exit(0);
                //close the form
            }

            //create the instance using the first pol process found
            _FFACE = new FFACE(pol[0].Id);
            string myName = _FFACE.Player.Name;

            myServer = _FFACE.Player.PlayerServerID;
            this.Text = "Maelu - Connected to: " + myName + "@" + Tools.getServerName(myServer);

            //Scan Info
            listBox1.Items.Add("");
            listBox1.Items.Add(" * " + _FFACE.Item.InventoryCount + " items in inventory.");
            listBox1.Items.Add(" * " + _FFACE.Item.SatchelCount + " items in satchel.");
            listBox1.Items.Add(" * " + _FFACE.Item.SafeCount + " items in safe.");
            listBox1.Items.Add(" * " + _FFACE.Item.SackCount + " items in sack.");
            listBox1.Items.Add(" * " + _FFACE.Item.StorageCount + " items in storage.");
            listBox1.Items.Add(" * " + _FFACE.Item.LockerCount + " items in locker.");
        }

        #region "-- Start screenscraper"
        /// <summary>
        /// Starts screenscraping for checked checkboxes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {

            listBox1.Items.Clear();
            //Check if user has checked anything.
            if (checkBox1.Checked || checkBox2.Checked || checkBox3.Checked || checkBox4.Checked || checkBox5.Checked || checkBox6.Checked)
            {
                listBox1.Items.Add("Screen scraper");
                listBox1.Items.Add(" - Starting..");
            }
            else
            {
                listBox1.Items.Add("Error");
                listBox1.Items.Add(" - No checkbox checked..");
            }

            if (checkBox1.Checked) //inventory
                getInventory();

            if (checkBox2.Checked) //locker
                getLocker();

            if (checkBox3.Checked) //sack
                getSack();

            if (checkBox4.Checked) //safe
                getSafe();

            if (checkBox5.Checked) //satchel
                getSatchel();

            if (checkBox6.Checked) //storage 
                getStorage();
        }
        #endregion

        #region "-- Un/check all"
        /// <summary>
        /// Check / Uncheck all storage checkboxes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            //Change text of un/check button.
            if (this.button2.Text == "Check All" && !this.checkBox1.Checked)
                this.button2.Text = "Uncheck All";
            else
                this.button2.Text = "Check All";

            if (this.checkBox1.Checked)
                this.checkBox1.Checked = false;
            else
                this.checkBox1.Checked = true;

            if (this.checkBox2.Checked)
                this.checkBox2.Checked = false;
            else
                this.checkBox2.Checked = true;

            if (this.checkBox3.Checked)
                this.checkBox3.Checked = false;
            else
                this.checkBox3.Checked = true;

            if (this.checkBox4.Checked)
                this.checkBox4.Checked = false;
            else
                this.checkBox4.Checked = true;

            if (this.checkBox5.Checked)
                this.checkBox5.Checked = false;
            else
                this.checkBox5.Checked = true;

            if (this.checkBox6.Checked)
                this.checkBox6.Checked = false;
            else
                this.checkBox6.Checked = true;
        }
        #endregion 


        #region "-- Inventory"

        public void getInventory()
        {
            var inventoryThread = new Thread(() =>
            {
                string loc = "Inventory";
                bool noPrice = false;

                for (int i = 1; i <= 80; i++)
                {
                    //Stop if checkbox is unchecked.
                    if (!checkBox1.Checked)
                        break;

                    //Skip none existing items in inventory.
                    try
                    {
                        //Get itemID and FFXIAH sourcecode.
                        int itemID = _FFACE.Item.GetInventoryItem(i).ID;
                        string source = ScreenScraper.getCookieSource(itemID, myServer);

                        //Regex to get name of item.
                        Match itemName = Regex.Match(source, regexItemName);
                        if (itemName.Success)
                        {
                            //If found, look for price info.
                            Match itemPrice = Regex.Match(source, regexItemPrice);
                            if (itemPrice.Success)
                                //If price is found add item to gistView.
                                this.InvokeEx(f => f.dataGridView1.Rows.Add(itemName.Groups[1], Tools.priceFormat(itemPrice.Groups[1].Value), loc));
                            else
                                //Set noPrice to true.
                                noPrice = true;
                        }
                        else
                        {
                            //No match found on ffxiah, write to listbox.
                            this.InvokeEx(f => f.listBox1.Items.Add("No match for item ID:" + itemID));
                        }

                        //Update listbox / counter.
                        if (noPrice)
                        {
                            noPrice = false;
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID + " (no price info..)");
                                f.listBox1.Refresh();
                            });
                        }
                        else
                        {
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID);
                                f.listBox1.Refresh();
                            });
                        }
                        //Antispam.
                        Thread.Sleep(antiSpam);
                    }
                    catch (Exception ex)
                    {
                        //Item don't exist, send info to listbox.
                        this.InvokeEx(f =>
                        {
                            f.listBox1.Items.Clear();
                            f.listBox1.Items.Add(loc);
                            f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                            f.listBox1.Items.Add(" - Don't exist.. (skipping)");
                            f.listBox1.Refresh();
                        });
                    }
                    Thread.Sleep(80);
                }
                //Done.
                this.InvokeEx(f =>
                {
                    f.listBox1.Items.Clear();
                    f.listBox1.Items.Add(loc);
                    f.listBox1.Items.Add(" - Done.");
                    f.checkBox1.Checked = false;
                });

            })
            {
                IsBackground = true
            };
            inventoryThread.Start();
        }
        #endregion

        #region "-- Locker"

        public void getLocker()
        {
            var lockerThread = new Thread(() =>
            {
                string loc = "Locker";
                bool noPrice = false;

                for (int i = 1; i <= 80; i++)
                {
                    //Stop if checkbox is unchecked.
                    if (!checkBox2.Checked)
                        break;

                    //Skip none existing items in inventory.
                    try
                    {
                        //Get itemID and FFXIAH sourcecode.
                        int itemID = _FFACE.Item.GetLockerItem(i).ID;
                        string source = ScreenScraper.getCookieSource(itemID, myServer);

                        //Regex to get name of item.
                        Match itemName = Regex.Match(source, regexItemName);
                        if (itemName.Success)
                        {
                            //If found, look for price info.
                            Match itemPrice = Regex.Match(source, regexItemPrice);
                            if (itemPrice.Success)
                                //If price is found add item to gistView.
                                this.InvokeEx(f => f.dataGridView1.Rows.Add(itemName.Groups[1], Tools.priceFormat(itemPrice.Groups[1].Value), loc));
                            else
                                //Set noPrice to true.
                                noPrice = true;
                        }
                        else
                        {
                            //No match found on ffxiah, write to listbox.
                            this.InvokeEx(f => f.listBox1.Items.Add("No match for item ID:" + itemID));
                        }

                        //Update listbox / counter.
                        if (noPrice)
                        {
                            noPrice = false;
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID + " (no price info..)");
                                f.listBox1.Refresh();
                            });
                        }
                        else
                        {
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID);
                                f.listBox1.Refresh();
                            });
                        }
                        //Antispam.
                        Thread.Sleep(antiSpam);
                    }
                    catch
                    {
                        //Item don't exist, send info to listbox.
                        this.InvokeEx(f =>
                        {
                            f.listBox1.Items.Clear();
                            f.listBox1.Items.Add(loc);
                            f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                            f.listBox1.Items.Add(" - Don't exist.. (skipping)");
                            f.listBox1.Refresh();
                        });
                    }
                    Thread.Sleep(80);
                }
                //Done.
                this.InvokeEx(f =>
                {
                    f.listBox1.Items.Clear();
                    f.listBox1.Items.Add(loc);
                    f.listBox1.Items.Add(" - Done.");
                    f.checkBox2.Checked = false;
                });

            })
            {
                IsBackground = true
            };
            lockerThread.Start();
        }
        #endregion

        #region "-- Sack"

        public void getSack()
        {
            var sackThread = new Thread(() =>
            {
                string loc = "Sack";
                bool noPrice = false;

                for (int i = 1; i <= 80; i++)
                {
                    //Stop if checkbox is unchecked.
                    if (!checkBox3.Checked)
                        break;

                    //Skip none existing items in inventory.
                    try
                    {
                        //Get itemID and FFXIAH sourcecode.
                        int itemID = _FFACE.Item.GetSackItem(i).ID;
                        string source = ScreenScraper.getCookieSource(itemID, myServer);

                        //Regex to get name of item.
                        Match itemName = Regex.Match(source, regexItemName);
                        if (itemName.Success)
                        {
                            //If found, look for price info.
                            Match itemPrice = Regex.Match(source, regexItemPrice);
                            if (itemPrice.Success)
                                //If price is found add item to gistView.
                                this.InvokeEx(f => f.dataGridView1.Rows.Add(itemName.Groups[1], Tools.priceFormat(itemPrice.Groups[1].Value), loc));
                            else
                                //Set noPrice to true.
                                noPrice = true;
                        }
                        else
                        {
                            //No match found on ffxiah, write to listbox.
                            this.InvokeEx(f => f.listBox1.Items.Add("No match for item ID:" + itemID));
                        }

                        //Update listbox / counter.
                        if (noPrice)
                        {
                            noPrice = false;
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID + " (no price info..)");
                                f.listBox1.Refresh();
                            });
                        }
                        else
                        {
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID);
                                f.listBox1.Refresh();
                            });
                        }
                        //Antispam.
                        Thread.Sleep(antiSpam);
                    }
                    catch
                    {
                        //Item don't exist, send info to listbox.
                        this.InvokeEx(f =>
                        {
                            f.listBox1.Items.Clear();
                            f.listBox1.Items.Add(loc);
                            f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                            f.listBox1.Items.Add(" - Don't exist.. (skipping)");
                            f.listBox1.Refresh();
                        });
                    }
                    Thread.Sleep(80);
                }
                //Done.
                this.InvokeEx(f =>
                {
                    f.listBox1.Items.Clear();
                    f.listBox1.Items.Add(loc);
                    f.listBox1.Items.Add(" - Done.");
                    f.checkBox3.Checked = false;
                });

            })
            {
                IsBackground = true
            };
            sackThread.Start();
        }
        #endregion

        #region "-- Safe"

        public void getSafe()
        {
            var safeThread = new Thread(() =>
            {
                string loc = "Safe";
                bool noPrice = false;

                for (int i = 1; i <= 80; i++)
                {
                    //Stop if checkbox is unchecked.
                    if (!checkBox4.Checked)
                        break;

                    //Skip none existing items in inventory.
                    try
                    {
                        //Get itemID and FFXIAH sourcecode.
                        int itemID = _FFACE.Item.GetSafeItem(i).ID;
                        string source = ScreenScraper.getCookieSource(itemID, myServer);

                        //Regex to get name of item.
                        Match itemName = Regex.Match(source, regexItemName);
                        if (itemName.Success)
                        {
                            //If found, look for price info.
                            Match itemPrice = Regex.Match(source, regexItemPrice);
                            if (itemPrice.Success)
                                //If price is found add item to gistView.
                                this.InvokeEx(f => f.dataGridView1.Rows.Add(itemName.Groups[1], Tools.priceFormat(itemPrice.Groups[1].Value), loc));
                            else
                                //Set noPrice to true.
                                noPrice = true;
                        }
                        else
                        {
                            //No match found on ffxiah, write to listbox.
                            this.InvokeEx(f => f.listBox1.Items.Add("No match for item ID:" + itemID));
                        }

                        //Update listbox / counter.
                        if (noPrice)
                        {
                            noPrice = false;
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID + " (no price info..)");
                                f.listBox1.Refresh();
                            });
                        }
                        else
                        {
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID);
                                f.listBox1.Refresh();
                            });
                        }
                        //Antispam.
                        Thread.Sleep(antiSpam);
                    }
                    catch
                    {
                        //Item don't exist, send info to listbox.
                        this.InvokeEx(f =>
                        {
                            f.listBox1.Items.Clear();
                            f.listBox1.Items.Add(loc);
                            f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                            f.listBox1.Items.Add(" - Don't exist.. (skipping)");
                            f.listBox1.Refresh();
                        });
                    }
                    Thread.Sleep(80);
                }
                //Done.
                this.InvokeEx(f =>
                {
                    f.listBox1.Items.Clear();
                    f.listBox1.Items.Add(loc);
                    f.listBox1.Items.Add(" - Done.");
                    f.checkBox4.Checked = false;
                });

            })
            {
                IsBackground = true
            };
            safeThread.Start();
        }
        #endregion

        #region "-- Satchel"

        public void getSatchel()
        {
            var satchelThread = new Thread(() =>
            {
                string loc = "Satchel";
                bool noPrice = false;

                for (int i = 1; i <= 80; i++)
                {
                    //Stop if checkbox is unchecked.
                    if (!checkBox5.Checked)
                        break;

                    //Skip none existing items in inventory.
                    try
                    {
                        //Get itemID and FFXIAH sourcecode.
                        int itemID = _FFACE.Item.GetSatchelItem(i).ID;
                        string source = ScreenScraper.getCookieSource(itemID, myServer);

                        //Regex to get name of item.
                        Match itemName = Regex.Match(source, regexItemName);
                        if (itemName.Success)
                        {
                            //If found, look for price info.
                            Match itemPrice = Regex.Match(source, regexItemPrice);
                            if (itemPrice.Success)
                                //If price is found add item to gistView.
                                this.InvokeEx(f => f.dataGridView1.Rows.Add(itemName.Groups[1], Tools.priceFormat(itemPrice.Groups[1].Value), loc));
                            else
                                //Set noPrice to true.
                                noPrice = true;
                        }
                        else
                        {
                            //No match found on ffxiah, write to listbox.
                            this.InvokeEx(f => f.listBox1.Items.Add("No match for item ID:" + itemID));
                        }

                        //Update listbox / counter.
                        if (noPrice)
                        {
                            noPrice = false;
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID + " (no price info..)");
                                f.listBox1.Refresh();
                            });
                        }
                        else
                        {
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID);
                                f.listBox1.Refresh();
                            });
                        }
                        //Antispam.
                        Thread.Sleep(antiSpam);
                    }
                    catch
                    {
                        //Item don't exist, send info to listbox.
                        this.InvokeEx(f =>
                        {
                            f.listBox1.Items.Clear();
                            f.listBox1.Items.Add(loc);
                            f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                            f.listBox1.Items.Add(" - Don't exist.. (skipping)");
                            f.listBox1.Refresh();
                        });
                    }
                    Thread.Sleep(80);
                }
                //Done.
                this.InvokeEx(f =>
                {
                    f.listBox1.Items.Clear();
                    f.listBox1.Items.Add(loc);
                    f.listBox1.Items.Add(" - Done.");
                    f.checkBox5.Checked = false;
                });

            })
            {
                IsBackground = true
            };
            satchelThread.Start();
        }
        #endregion

        #region "-- Storage"

        public void getStorage()
        {
            var storageThread = new Thread(() =>
            {
                string loc = "Storage";
                bool noPrice = false;

                for (int i = 1; i <= 80; i++)
                {
                    //Stop if checkbox is unchecked.
                    if (!checkBox6.Checked)
                        break;

                    //Skip none existing items in inventory.
                    try
                    {
                        //Get itemID and FFXIAH sourcecode.
                        int itemID = _FFACE.Item.GetSatchelItem(i).ID;
                        string source = ScreenScraper.getCookieSource(itemID, myServer);

                        //Regex to get name of item.
                        Match itemName = Regex.Match(source, regexItemName);
                        if (itemName.Success)
                        {
                            //If found, look for price info.
                            Match itemPrice = Regex.Match(source, regexItemPrice);
                            if (itemPrice.Success)
                                //If price is found add item to gistView.
                                this.InvokeEx(f => f.dataGridView1.Rows.Add(itemName.Groups[1], Tools.priceFormat(itemPrice.Groups[1].Value), loc));
                            else
                                //Set noPrice to true.
                                noPrice = true;
                        }
                        else
                        {
                            //No match found on ffxiah, write to listbox.
                            this.InvokeEx(f => f.listBox1.Items.Add("No match for item ID:" + itemID));
                        }

                        //Update listbox / counter.
                        if (noPrice)
                        {
                            noPrice = false;
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID + " (no price info..)");
                                f.listBox1.Refresh();
                            });
                        }
                        else
                        {
                            this.InvokeEx(f =>
                            {
                                f.listBox1.Items.Clear();
                                f.listBox1.Items.Add(loc);
                                f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                                f.listBox1.Items.Add(" - Current item ID: " + itemID);
                                f.listBox1.Refresh();
                            });
                        }
                        //Antispam.
                        Thread.Sleep(antiSpam);
                    }
                    catch
                    {
                        //Item don't exist, send info to listbox.
                        this.InvokeEx(f =>
                        {
                            f.listBox1.Items.Clear();
                            f.listBox1.Items.Add(loc);
                            f.listBox1.Items.Add(" - Checking items: " + i + "/" + 80);
                            f.listBox1.Items.Add(" - Don't exist.. (skipping)");
                            f.listBox1.Refresh();
                        });
                    }
                    Thread.Sleep(80);
                }
                //Done.
                this.InvokeEx(f =>
                {
                    f.listBox1.Items.Clear();
                    f.listBox1.Items.Add(loc);
                    f.listBox1.Items.Add(" - Done.");
                    f.checkBox6.Checked = false;
                });

            })
            {
                IsBackground = true
            };
            storageThread.Start();
        }
        #endregion

        #region "-- CheckBox_CheckedChanged"

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
                antiSpam += 617;
            else
                antiSpam -= 617;
            listBox1.Items.Clear();
            listBox1.Items.Add("Screen scraper");
            listBox1.Items.Add(" - Anti-spam: " + antiSpam + "ms");
        }

        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked)
                antiSpam += 617;
            else
                antiSpam -= 617;
            listBox1.Items.Clear();
            listBox1.Items.Add("Screen scraper");
            listBox1.Items.Add(" - Anti-spam: " + antiSpam + "ms");
        }

        private void checkBox3_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox3.Checked)
                antiSpam += 617;
            else
                antiSpam -= 617;
            listBox1.Items.Clear();
            listBox1.Items.Add("Screen scraper");
            listBox1.Items.Add(" - Anti-spam: " + antiSpam + "ms");
        }

        private void checkBox4_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox4.Checked)
                antiSpam += 617;
            else
                antiSpam -= 617;
            listBox1.Items.Clear();
            listBox1.Items.Add("Screen scraper");
            listBox1.Items.Add(" - Anti-spam: " + antiSpam + "ms");
        }

        private void checkBox5_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox5.Checked)
                antiSpam += 617;
            else
                antiSpam -= 617;
            listBox1.Items.Clear();
            listBox1.Items.Add("Screen scraper");
            listBox1.Items.Add(" - Anti-spam: " + antiSpam + "ms");
        }

        private void checkBox6_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox6.Checked)
                antiSpam += 617;
            else
                antiSpam -= 617;
            listBox1.Items.Clear();
            listBox1.Items.Add("Screen scraper");
            listBox1.Items.Add(" - Anti-spam: " + antiSpam + "ms");
        }
        #endregion

        #region "-- Item Search"
        /// <summary>
        /// source: http://stackoverflow.com/a/1328617
        /// datagridview search
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void textBox1_TextChanged(object sender, EventArgs e)
        {
            foreach (DataGridViewRow row in dataGridView1.Rows)
                row.Visible = true;

            foreach (DataGridViewRow row in dataGridView1.Rows)
            {
                try
                {
                    if (!Convert.ToString(row.Cells[0].Value).Contains(textBox1.Text))
                        row.Visible = false;
                }
                catch
                {
                    //nothing
                }
            }
        }
        #endregion
    }
}
